/**
 * 选择节点类型
 *
 * @class NodetypeSelectionBubble
 * @constructor
 */

var NodetypeSelectionBubble = Class.create({

    buttonsDefs : [
        {
            key: "M",
            type: "person",
            label: "Male",
            tip  : "添加男性",
            symbol: "",
            cssclass: "fa fa-square-o",
            callback : "CreateChild",
            params: { "brothers": true, "parameters": {"gender": "M"} },
            expandsTo: 'expandBrothers',
            inSiblingMode: true
        }, {
            key: "F",
            type: "person",
            label: "Female",
            tip  : "添加女性",
            symbol: "",
            cssclass: "fa fa-circle-thin",
            callback : "CreateChild",
            params: { "sisters": true, "parameters": {"gender": "F"} },
            expandsTo: 'expandSisters',
            inSiblingMode: true
        },
        {
            key: "U",
            type: "person",
            label: "Unknown",
            tip  : "添加性别未知个人",
            symbol: "<div class='fa fa-square-o fa-rotate-45'></div>",
            cssclass: "",
            callback : "CreateChild",
            params: { "unknowns": true, "parameters": {"gender": "U"} },
            expandsTo: 'expandUnknowns',
            inSiblingMode: true
        }, {
            key: "T",
            type: "person",
            label: "Twins",
            tip  : "添加双胞胎 (展开可添加三胞胎或更多)",
            symbol: "⋀",
            cssclass: "",
            callback : "CreateChild",
            params: { "twins": true, "parameters": {"gender": "F"} },
            expandsTo: 'expandTwins',
            inSiblingMode: true
        },
           {
            key: "m",
            type: "person",
            label: "Multiple",
            tip  : "添加一个代表多个兄弟姐妹的节点",
            symbol: "〈n〉",
            cssclass: "",
            callback : "CreateChild",
            params: { "group": true , "parameters": {"gender": "U"}},//初始化多子女集合性别符号，否则为男
            expandsTo: "expandPersonGroup",
            inSiblingMode: true
        }
    ],

    initialize : function(siblingMode) {
        this._siblingMode = siblingMode;

        this.element = new Element('div', {'class' : 'callout'});
        this.element.insert(new Element('span', {'class' : 'callout-handle'}));

        var container = new Element('div', {'class' : 'node-type-options'});
        this.expandedOptionsContainer = new Element('div', {'class' : 'node-type-options-extended'});
        this.element.insert(container);
        this.element.insert(this.expandedOptionsContainer);

        var _this = this;
        this.buttonsDefs.each(function(def) {
            if (!siblingMode || (def.hasOwnProperty("inSiblingMode") && def.inSiblingMode))
                container.insert(def.type == 'separator' ? _this._generateSeparator() : _this._createOption(def));
        });
        this.element.hide();
        editor.getWorkspace().getWorkArea().insert(this.element);

        this._onClickOutside = this._onClickOutside.bindAsEventListener(this);

        this.resetParameters();
    },

    resetParameters: function() {
        this.numPersonsInGroup = 1;
        this.numTwinNodes      = 2;
        //===
        this.numBrotherNodes      = 1;
        this.numSisterNodes      = 1;
        this.numUnknownNodes      = 1;
    },

    /**
     *
     * @method _createOption
     * @param data 
     * @return {HTMLElement} 
     * @private
     */
    _createOption : function(data) {
        var i = 1;
        if(!data) {
            return null;
        }
        var expandablePrefix = (typeof this[data.expandsTo] == "function") ? "expandable-" : "";
        var o = new Element('a', {
            'class' : data.cssclass + ' ' + expandablePrefix + 'node-type-option ' + (data.type || '') + '-type-option node-type-' + data.key,
            'title' : data.tip,
            'href' : '#'
        }).update(data.symbol); 
        var _this = this;
        o.observe('click', function(event) {
            event.stop();
            if (!_this._node) return;
            console.log("observe nodetype click: " + data.callback);
            if (data.callback == "setProperty") {
                var event = { "nodeID": _this._node.getID(), "properties": data.params };
                document.fire("pedigree:node:setproperty", event);
            }
            else if (data.callback == "CreateChild") {
                _this.handleCreateAction(data);
            }
            _this.hide();
        });
        var container = new Element("span");
        container.insert(o);
        expandablePrefix && container.insert(this.generateExpandArrow(data));
        return container;
    },
    handleCreateAction: function(data) {
    		var isBrothersGroup = '';
    		var isSistersGroup = '';
    		var isUnkownsGroup = '';
        var id       = this._node.getID();
        var nodeType = this._node.getType();
        if (nodeType == "Person") {
            var event = { "personID": id, "childParams": data.params.parameters, "preferLeft": false };
            if (data.params.twins) {
                event["twins"] = this.numTwinNodes;
            }
        		if (data.params.brothers) {
                event["brothers"] = this.numBrotherNodes;
                
            }
        		if (data.params.sisters) {
                event["sisters"] = this.numSisterNodes;
            }
        		if (data.params.unknowns) {
                event["unknowns"] = this.numUnknownNodes;
           }        
            if (data.params.group) {
                event["groupSize"] = this.numPersonsInGroup;
            }

            if (this._siblingMode)
                document.fire("pedigree:person:newsibling", event);
            else
                document.fire("pedigree:person:newpartnerandchild", event);
        }
        else if (nodeType == "Partnership") {
            console.log('bbb');
            var event = { "partnershipID": id, "childParams": data.params.parameters };
            if (data.params.twins) {
                event["twins"] = this.numTwinNodes;
            }
            if (data.params.brothers) {
                event["brothers"] = this.numBrotherNodes;
            }
        		if (data.params.sisters) {
                event["sisters"] = this.numSisterNodes;
            }
        		if (data.params.unknowns) {
                event["unknowns"] = this.numUnknownNodes;
            }
            if (data.params.group) {
                event["groupSize"] = this.numPersonsInGroup;
            }
            document.fire("pedigree:partnership:newchild", event);
        }
        this.hide();
    },

    /**
     *
     * @method generateExpandArrow
     * @param data 
     * @return {HTMLElement} 
     */
    generateExpandArrow: function(data) {
        var expandArrow = new Element('span', {
            'class' : 'expand-arrow collapsed',
            'title' : "设置更多选项",
            'href' : '#'
        }).update("▾");

        expandArrow.expand = function() {
            $$(".expand-arrow").forEach(function(arrow) {arrow.collapse()});
            this[data.expandsTo](data);
            expandArrow.update("▴");
            Element.removeClassName(expandArrow, "collapsed");
        }.bind(this);

        expandArrow.collapse = function() {
            this.expandedOptionsContainer.update("");
            expandArrow.update("▾");
            Element.addClassName(expandArrow, "collapsed");
        }.bind(this);

        expandArrow.observe("click", function() {
            console.log("observe2");
            if(expandArrow.hasClassName("collapsed")) {
                expandArrow.expand();
            }
            else {
                expandArrow.collapse();
            }
        });
        return expandArrow;
    },

    /**
     *
     * @method _generateSeparator
     * @return {HTMLElement}
     * @private
     */
    _generateSeparator : function() {
        return new Element('span', {'class' : 'separator'}).update(' | ');
    },

    /**
     * @method _positionAt
     * @param {Number} x The 
     * @param {Number} y The 
     * @private
     */
    _positionAt : function(x, y) {
        y = Math.round(y);
        if (y + this.element.getHeight() > editor.getWorkspace().getWorkArea().getHeight()) {
            this.element.addClassName("upside");
            y = Math.round(y - this.element.getHeight());
        }
        this.element.style.top = y + 40 + "px";
        var dx = Math.round(this.element.getWidth()/2);
        if (x - dx + this.element.getWidth() > editor.getWorkspace().getWorkArea().getWidth()) {
            dx = Math.round(this.element.getWidth() - (editor.getWorkspace().getWorkArea().getWidth() - x));
        } else if (dx > x) {
            dx = Math.round(x);
        }
        this.element.down('.callout-handle').style.left = dx  + "px";
        this.element.style.left = Math.round(x - dx) + 5 + "px";
    },

    /**
     *
     * @method show
     * @param {AbstractNode} node 
     * @param {Number} x 
     * @param {Number} y 
     */
    show : function(node, x, y) {
        this._node = node;
        if (!this._node) return;
        this._node.onWidgetShow();
        this.element.show();
        this.expandedOptionsContainer.update("");
        this._positionAt(x, y);
        document.observe('mousedown', this._onClickOutside);
    },

    /**
     *
     * @method hide
     */
    hide : function() {
        document.stopObserving('mousedown', this._onClickOutside);
        $$(".expand-arrow").forEach(function(arrow) {
            arrow.collapse();
        });
        if (this._node) {
            this._node.onWidgetHide();
            delete this._node;
            this.element.select('.node-type-option').invoke('show');
            this.element.removeClassName("upside");
        }
        this.element.hide();
        this.resetParameters();  
    },

    /**
     *
     * @method _onClickOutside
     * @param {Event} event
     * @private
     */
    _onClickOutside: function (event) {
        if (!event.findElement('.callout')) {
            this.hide();
        }
    },

    /**
     *
     * @method _decrementNumNodes
     * @return {Number} 
     * @private
     */
    _decrementNumNodes: function() {
        return this.numPersonsInGroup > 1 ? --this.numPersonsInGroup : this.numPersonsInGroup;
    },

    /**
     *
     * @method _incrementNumNodes
     * @return {Number} 
     * @private
     */
    _incrementNumNodes: function() {
        return this.numPersonsInGroup < 9 ? ++this.numPersonsInGroup : this.numPersonsInGroup;
    },

    /**
     *
     * @method _decrementNumTwins
     * @return {Number} 
     * @private
     */
    _decrementNumTwins: function() {
        return this.numTwinNodes > 2 ? --this.numTwinNodes : this.numTwinNodes;
    },

    /**
     *
     * @method _incrementNumTwins
     * @return {Number} 
     * @private
     */
    _incrementNumTwins: function() {
        return this.numTwinNodes < 9 ? ++this.numTwinNodes : this.numTwinNodes;
    },
    //===
    
	/**
     * Brother
     * @method _decrementNumBrothers
     * @return {Number} 
     * @private
     */
    _decrementNumBrothers: function() {
        return this.numBrotherNodes > 1 ? --this.numBrotherNodes : this.numBrotherNodes;
    },

    /**
     *
     * @method _incrementNumBrothers
     * @return {Number} 
     * @private
     */
    _incrementNumBrothers: function() {
        return this.numBrotherNodes < 9 ? ++this.numBrotherNodes : this.numBrotherNodes;
    },
    
	/**
     * Sister
     * @method _decrementNumSisters
     * @return {Number} 
     * @private
     */
    _decrementNumSisters: function() {
        return this.numSisterNodes > 1 ? --this.numSisterNodes : this.numSisterNodes;
    },

    /**
     *
     * @method _incrementNumSisters
     * @return {Number} 
     * @private
     */
    _incrementNumSisters: function() {
        return this.numSisterNodes < 9 ? ++this.numSisterNodes : this.numSisterNodes;
    },
	/**
     * Unkown
     * @method _decrementNumUnknowns
     * @return {Number} 
     * @private
     */
    _decrementNumUnknowns: function() {
        return this.numUnknownNodes > 1 ? --this.numUnknownNodes : this.numUnknownNodes;
    },
    /**
     *
     * @method _incrementNumUnknowns
     * @return {Number} 
     * @private
     */
     _incrementNumUnknowns: function() {
        return this.numUnknownNodes < 9 ? ++this.numUnknownNodes : this.numUnknownNodes;
    },
   
    /**
     *
     * @method expandBrothers
     */
    expandBrothers: function(brotherMenuInfo) {
        var me = this;
        var generateIcon = function(){
            return '<svg version="1.1" viewBox="0.0 0.0 100.0 100.0" width=50 height=50 fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l960.0 0l0 720.0l-960.0 0l0 -720.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l960.0 0l0 720.0l-960.0 0z" fill-rule="nonzero"></path></path><path fill="#000000" fill-opacity="0.0" d="m20.661417 22.068241l58.204727 0l0 48.000004l-58.204727 0z" fill-rule="nonzero"></path></g><desc>Number of children</desc><text x="35" y="60" font-family="Verdana" font-size="40" fill="black">'
                + me.numBrotherNodes + '</text></svg>';
        };
        var createBtn = new Element("input", {'type': 'button', 'value': '添加男性', 'class': 'button'});
        var svgContainer = new Element('span').update(generateIcon());
        var minusBtn = new Element("span", {
            "class": 'minus-button value-control-button'
        }).update("-");
        var plusBtn = new Element("span", {
            "class": 'plus-button value-control-button'
        }).update("+");
        minusBtn.observe("click", function() { me._decrementNumBrothers(); svgContainer.update(generateIcon())});
        plusBtn.observe("click",  function() { me._incrementNumBrothers(); svgContainer.update(generateIcon())});
        createBtn.observe("click", function() {
            me.handleCreateAction(brotherMenuInfo);
        });
        this.expandedOptionsContainer.insert(minusBtn);
        this.expandedOptionsContainer.insert(svgContainer);
        this.expandedOptionsContainer.insert(plusBtn);
        this.expandedOptionsContainer.insert(createBtn);
    },
    
    /** 
     * 
     * @method expandSisters
     */
    expandSisters: function(sisterMenuInfo) {
        var me = this;
        var generateIcon = function(){
            return '<svg version="1.1" viewBox="0.0 0.0 100.0 100.0" width=50 height=50 fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l960.0 0l0 720.0l-960.0 0l0 -720.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l960.0 0l0 720.0l-960.0 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m20.661417 22.068241l58.204727 0l0 48.000004l-58.204727 0z" fill-rule="nonzero"></path></g><desc>Number of children</desc><text x="35" y="60" font-family="Verdana" font-size="40" fill="black">'
                + me.numSisterNodes + '</text></svg>';
        };
        var createBtn = new Element("input", {'type': 'button', 'value': '添加女性', 'class': 'button'});
        var svgContainer = new Element('span').update(generateIcon());
        var minusBtn = new Element("span", {
            "class": 'minus-button value-control-button'
        }).update("-");
        var plusBtn = new Element("span", {
            "class": 'plus-button value-control-button'
        }).update("+");
        minusBtn.observe("click", function() { me._decrementNumSisters(); svgContainer.update(generateIcon())});
        plusBtn.observe("click",  function() { me._incrementNumSisters(); svgContainer.update(generateIcon())});
        createBtn.observe("click", function() {
            me.handleCreateAction(sisterMenuInfo);
        });
        this.expandedOptionsContainer.insert(minusBtn);
        this.expandedOptionsContainer.insert(svgContainer);
        this.expandedOptionsContainer.insert(plusBtn);
        this.expandedOptionsContainer.insert(createBtn);
    },
    /**
     *
     * @method expandUnknowns
     */
    expandUnknowns: function(unknownMenuInfo) {
        var me = this;
        var generateIcon = function(){
            return '<svg version="1.1" viewBox="0.0 0.0 100.0 100.0" width=50 height=50 fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l960.0 0l0 720.0l-960.0 0l0 -720.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l960.0 0l0 720.0l-960.0 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m20.661417 22.068241l58.204727 0l0 48.000004l-58.204727 0z" fill-rule="nonzero"></path></g><desc>Number of children</desc><text x="35" y="60" font-family="Verdana" font-size="40" fill="black">'
                + me.numUnknownNodes + '</text></svg>';
        };
        var createBtn = new Element("input", {'type': 'button', 'value': '添加性别未知', 'class': 'button'});
        var svgContainer = new Element('span').update(generateIcon());
        var minusBtn = new Element("span", {
            "class": 'minus-button value-control-button'
        }).update("-");
        var plusBtn = new Element("span", {
            "class": 'plus-button value-control-button'
        }).update("+");
        minusBtn.observe("click", function() { me._decrementNumUnknowns(); svgContainer.update(generateIcon())});
        plusBtn.observe("click",  function() { me._incrementNumUnknowns(); svgContainer.update(generateIcon())});
        createBtn.observe("click", function() {
            me.handleCreateAction(unknownMenuInfo);
        });
        this.expandedOptionsContainer.insert(minusBtn);
        this.expandedOptionsContainer.insert(svgContainer);
        this.expandedOptionsContainer.insert(plusBtn);
        this.expandedOptionsContainer.insert(createBtn);
    },
   
    /**
     *
     * @method expandPersonGroup
     */

    expandPersonGroup: function(personGroupMenuInfo) {
        var me = this;
        var generateIcon = function(){
                var iconText = (me.numPersonsInGroup > 1) ? String(me.numPersonsInGroup) : "n";
                return '<svg version="1.1" viewBox="0.0 0.0 100.0 100.0" width=50 height=50 fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l960.0 0l0 720.0l-960.0 0l0 -720.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l960.0 0l0 720.0l-960.0 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m20.661417 22.068241l58.204727 0l0 48.000004l-58.204727 0z" fill-rule="nonzero"></path></g><desc>Number of children</desc><text x="35" y="60" font-family="Verdana" font-size="40" fill="black">'
                    + iconText + '</text></svg>';

        };
        var createBtn = new Element("input", {'type': 'button', 'value': '添加个体集合', 'class': 'button'});
        var svgContainer = new Element('span').update(generateIcon());
        var minusBtn = new Element("span", {
            "class": 'minus-button value-control-button'
        }).update("-");
        var plusBtn = new Element("span", {
            "class": 'plus-button value-control-button'
        }).update("+");
        minusBtn.observe("click", function() { me._decrementNumNodes(); svgContainer.update(generateIcon())});
        plusBtn.observe ("click", function() { me._incrementNumNodes(); svgContainer.update(generateIcon())});
        createBtn.observe("click", function() {
            //console.log("observeCreate1");
            me.handleCreateAction(personGroupMenuInfo);
        });
        this.expandedOptionsContainer.insert(minusBtn);
        this.expandedOptionsContainer.insert(svgContainer);
        this.expandedOptionsContainer.insert(plusBtn);
        this.expandedOptionsContainer.insert(createBtn);
	},

    /**     
     * @method expandTwins
     */
    expandTwins: function(twinMenuInfo) {
        var me = this;
        var generateIcon = function(){
            return '<svg version="1.1" viewBox="0.0 0.0 100.0 100.0" width=50 height=50 fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l960.0 0l0 720.0l-960.0 0l0 -720.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l960.0 0l0 720.0l-960.0 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m20.661417 22.068241l58.204727 0l0 48.000004l-58.204727 0z" fill-rule="nonzero"></path></g><desc>Number of children</desc><text x="35" y="60" font-family="Verdana" font-size="40" fill="black">'
                + me.numTwinNodes + '</text></svg>';
        };
        var createBtn = new Element("input", {'type': 'button', 'value': '添加多胞胎', 'class': 'button'});
        var svgContainer = new Element('span').update(generateIcon());
        var minusBtn = new Element("span", {
            "class": 'minus-button value-control-button'
        }).update("-");
        var plusBtn = new Element("span", {
            "class": 'plus-button value-control-button'
        }).update("+");
        minusBtn.observe("click", function() { me._decrementNumTwins(); svgContainer.update(generateIcon())});
        plusBtn.observe("click",  function() { me._incrementNumTwins(); svgContainer.update(generateIcon())});        
        createBtn.observe("click", function() {
            me.handleCreateAction(twinMenuInfo);
        });
        this.expandedOptionsContainer.insert(minusBtn);
        this.expandedOptionsContainer.insert(svgContainer);
        this.expandedOptionsContainer.insert(plusBtn);
        this.expandedOptionsContainer.insert(createBtn);
    }
});